﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using Chemistry.Models;
using Chemistry.Tools;
using Chemistry.WorkFlow;
using GalaSoft.MvvmLight.Command;
using GLCommon;
using Novacode;

namespace Chemistry.ViewModels
{
    /// <summary>
    /// 直接进入考试
    /// </summary>
    public class DirectExamingViewModel:VmBase
    {
        private ExamInfo _examinfo;
        private bool _canLeakTriggere;
        private WorkFlowBase _currentFlow;
        private const int TotalMinute = 30;//考试时间 （分钟）
        private CancellationTokenSource _cts;
        private ConfigModel _configmodel;

        public RelayCommand RollCommand { get; set; }
        public RelayCommand CheckDetailCommand { get; set; }
        public RelayCommand PrintCommand { get; set; }
        public RelayCommand LeakAbnormalCommand { get; set; }
        #region 属性
    

        private DateTime _remain;

        public DateTime Remain
        {
            get { return _remain; }
            set { _remain = value; RaisePropertyChanged("Remain"); }
        }

        private bool _isover;

        public bool IsOver
        {
            get { return _isover; }
            set { _isover = value; RaisePropertyChanged("IsOver"); }
        }

        private int _score;

        public int Score
        {
            get { return _score; }
            set { _score = value; RaisePropertyChanged("Score"); }
        }

        private string _message;

        public string Message
        {
            get { return _message; }
            set { _message = value; RaisePropertyChanged("Message"); }
        }
      

        #endregion

        public DirectExamingViewModel()
        {
            RollCommand = new RelayCommand(RollExec, () =>  !IsOver);
            CheckDetailCommand = new RelayCommand(CheckDetailExec, () => IsOver);
            PrintCommand = new RelayCommand(PrintExec, () => IsOver);
            LeakAbnormalCommand = new RelayCommand(LeakAbnormalExec, () => !IsOver && _canLeakTriggere);
            InitMessage();
        }

        private void InitMessage()
        {
            Register<ExamInfoMessage>(
               this,
               MessageToken.ShowDirectExamingWindow,
               (i) =>
               {
                   _examinfo = i.ExamInfo;
                   _currentFlow = i.WorkFlow;
                   if (i.IsFirstShow)
                   {
                       InitFiled();
                       InitState();
                       _configmodel = Tool.GetConfig();
                       i.WorkFlow.FinishHandler += WorkFlow_FinishHandler;
                       i.WorkFlow.MessageHandler += WorkFlow_MessageHandler;
                   }
               });

            Register<object>(this, MessageToken.StopExaming,
                 (i) =>
                 {
                     if (_cts != null)
                         _cts.Cancel();
                 });
        }

        private void InitFiled()
        {
            IsOver = false;
            Message = string.Empty;
            _canLeakTriggere = true;
        }

        private void InitState()
        {
            _cts = new CancellationTokenSource();
            DateTime endtime = DateTime.Now.AddMinutes(TotalMinute);
            Task t = new Task(() =>
            {
                while (!_cts.IsCancellationRequested)
                {
                    var remain = (endtime - DateTime.Now).TotalSeconds;

                    if (remain > 0)
                    {
                        var minute = (int)remain / 60;
                        var second = (int)remain % 60;
                        Remain = new DateTime(2014, 1, 1, 1, minute, second);
                        Send<bool>(true, MessageToken.IsExaming);
                    }
                    else
                    {
                        _cts.Cancel();
                        if (_examinfo.ExamState == ExamState.考试中)
                        {
                            Roll();
                        }
                    }
                }
            });
            t.Start();
        }

        

        private void WorkFlow_MessageHandler(string message)
        {
            Message = !string.IsNullOrEmpty(message) ? string.Format("{0}\t{1}", message, DateTime.Now.ToString("HH:mm:ss")) : "";
        }

        private void WorkFlow_FinishHandler()
        {
            _examinfo.ExamState = ExamState.考试完成;
            int score = _currentFlow.Score;
            _examinfo.Score = score;
            this.Score = score;
            IsOver = true;
            Send<bool>(false, MessageToken.IsExaming);
            Message = string.Format("考试结束，得分：{0}", Score);
        }

        #region 命令方法
        private void CheckDetailExec()
        {
            Send<string>(_currentFlow.Content, MessageToken.CheckDetail);
        }

        private void PrintExec()
        {
             try
           {
               string startUpPath = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
               DocX doc = DocX.Load(startUpPath + "print\\new.docx");
               doc.ReplaceText("$flowname$", _configmodel.WorkflowChineseName);
               doc.ReplaceText("$company$", "");
               doc.ReplaceText("$index$", (Global.PrintIndex++).ToString());
               doc.ReplaceText("$number$", "");
               doc.ReplaceText("$name$", "");

               doc.ReplaceText("$step$", _currentFlow.Content);
               doc.ReplaceText("$score$", (_examinfo.Score * 0.5).ToString());
               string path = _configmodel.PrintPath ?? "C:\\print";
               string filename = string.Format("{0}.doc", (DateTime.Now.ToString("yyyyMMddhhmmss")));
               var savepath = _configmodel.PrintPath + "\\" + filename;
               doc.SaveAs(savepath);
               doc.Dispose();
               Process.Start(savepath);
               Message = "打印完成";
           }
           catch (Exception ex)
           {
               LogTool.WriteErrorLog(ex);
           }
        }

        private void LeakAbnormalExec()
        {
           _canLeakTriggere = false;
           _currentFlow.LeakageAbnormal();
        }

        private void RollExec()
        {
            if (MessageBox.Show("确定要交卷吗？", "提示", MessageBoxButton.OKCancel, MessageBoxImage.Question)
                == MessageBoxResult.OK)
            {
                Roll();
            }
        } 
        #endregion
        private void Roll()
        {
            try
            {
                _cts.Cancel();
                _currentFlow.Over();
            }
            catch (Exception e)
            {
                //ExamInfo.Permission.CanCommit = true;
                this.Message = "异常： " + e.Message;
                LogTool.WriteErrorLog(e.StackTrace);
                LogTool.WriteErrorLog(e.Message, e);
            }
        }
    }
}
